package org.example.iot.batch;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 模拟 静压水准仪
 */
public class TestBath0x0003_1 {

    public static void main(String[] args) throws InterruptedException {
        String prefix="JINGYSZ";

        for (int i=1;i<=30;i++){
            try {
                Thread.sleep(3000);
                NioEventLoopGroup worker = new NioEventLoopGroup();
                Bootstrap bootstrap = new Bootstrap();
                bootstrap.channel(NioSocketChannel.class);
                bootstrap.group(worker);
                bootstrap.option(NioChannelOption.TCP_NODELAY, true);
                int finalI = i;
                bootstrap.handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                            //和服务器建立连接之后的回调
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                System.out.println("连接建立");
                                //执行登录
                                String format = String.format("%09d", finalI);
                                String deviceNo= prefix+format;
                                System.out.println("设备："+deviceNo+"执行登录");
                                String deviceNoHex = ByteBufUtil.hexDump(deviceNo.getBytes());
                                byte[] loginBytes = ByteBufUtil.decodeHexDump("028f525c650099000101" +
                                        deviceNoHex +
                                        "322e30322e30303031015b525c6538363531333730363131313638383934363030383435343337303332383338393836303443353130323232303237333238331f3c1f0301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009f130d0a");
                                ctx.writeAndFlush(Unpooled.buffer().writeBytes(loginBytes));
                                Thread.sleep(1000);
                                /**
                                 * 025034dc5f002b000202010101014457475a434a59323331323138313032010101014457475a434a5932333132313831303376b50d0a
                                 */
                                //上报传感器信息
                                //头部
                                byte[] bytes1 = ByteBufUtil.decodeHexDump("025034dc5f");

                                ByteBuf byteBuf= ByteBufAllocator.DEFAULT.buffer();
                                byteBuf.writeBytes(bytes1);

                                int shakeNumber=50;

                                //数据长度 = 指令码 + 传感器数量 + 传感器信息
                                byteBuf.writeShort(2+1+(20*shakeNumber));
                                //写入指令码
                                byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0002"));
                                //写入传感器数量
                                byteBuf.writeByte(shakeNumber);

                                for (int j=1;j<=shakeNumber;j++){
                                    String toHexString = String.format("%02x", j);
                                    //写入20字节445747
                                    byteBuf.writeBytes(ByteBufUtil.decodeHexDump(toHexString+"010201"));
                                    byteBuf.writeBytes("DWGZCJY231100001".getBytes(StandardCharsets.UTF_8));
                                }

                                //写入CRE
                                byte[] crcBytes = crc16CCITTFalse(ByteBufUtil.getBytes(byteBuf));
                                byteBuf.writeBytes(crcBytes);
                                //写入尾部
                                byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0d0a"));
                                ctx.writeAndFlush(byteBuf);

                                /**
                                 * 上传数据包
                                 */
                                while (true){
                                    for (int j=1;j<=shakeNumber;j++){

                                        ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
                                        buf.writeBytes(ByteBufUtil.decodeHexDump("029A9915BF00150003" +
                                                //设备数据是1，每一次就发送一个传感器数据包
                                                "01" +
                                                //传感器地址
                                                String.format("%02x", j) +
                                                "00"
                                        ));
                                        int time = (int) (new Date().getTime() / 1000);
                                        buf.writeIntLE(time);

                                        Random random = new Random();
                                        DecimalFormat df1 = new DecimalFormat("#.00");

                                        String format1 = df1.format(random.nextFloat());
                                        buf.writeFloatLE(Float.valueOf(format1));


                                        String format2 = df1.format(random.nextFloat());
                                        buf.writeFloatLE(Float.valueOf(format2));


                                        byte[] bytes = ByteBufUtil.decodeHexDump("00000000E5420D0A");
                                        buf.writeBytes(bytes);
                                        ctx.writeAndFlush(buf);
                                    }
                                    Thread.sleep(1500L);
                                }
                            }
                        });
                    }
                });
                ChannelFuture channelFuture = bootstrap.connect("139.224.36.172", 9876).sync();
                Channel channel = channelFuture.channel();
            }catch (Exception exception){
                exception.printStackTrace();
            }
        }
    }
    public static byte[] crc16CCITTFalse(byte[] bytes) {
        int crc = 0xffff; // initial value
        int polynomial = 0x1021; // poly value
        for (int index = 0; index < bytes.length; index++) {
            byte b = bytes[index];
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit){
                    crc ^= polynomial;
                }
            }
        }
        crc &= 0xffff;
        return new byte[] { (byte) ((0xff00 & crc) >> 8),(byte) (0xff & crc)  };
    }

}
